package com.tg.appcommon.android;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.SimpleTarget;
import com.bumptech.glide.request.target.Target;
import com.bumptech.glide.request.transition.Transition;
import com.module.appcommon.R;
import com.tange.base.toolkit.StringUtils;
import com.tange.base.toolkit.TGThreadPool;
import com.tg.appcommon.transform.GrayscaleTransformation;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Describe:
 * Created by Rance Rang on 2019-08-27.
 * <p>
 * Copyright (c) Tange.Inc All rights reserved.
 */
public class ImageUtils {
    public static final String TAG = ImageUtils.class.getSimpleName();

    public static int saveFile(Context context, Bitmap bitmap) {
        String path = getScreenFileName();
        return  saveFile(context,bitmap,path);
    }
    public static String getScreenFileName(){
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        String dateString = formatter.format(new Date());
        String picName = String.format("demoScreenshot%s", dateString);
        //系统相册目录
        String galleryPath = Environment.getExternalStorageDirectory()
                + File.separator + Environment.DIRECTORY_DCIM;

        String path = String.format("%s/%s.jpg",galleryPath,picName);
        return  path;
    }

    public static boolean downloadImage(String url){
        String name = AbMd5.MD5(url);
        String format = url.substring(url.lastIndexOf("."));
        if (!StringUtils.equalsIgnoreCase(format, ".png") && !StringUtils.equalsIgnoreCase(format, ".jpeg") && !StringUtils.equalsIgnoreCase(format, ".jpg")){
            name += ".jpg";
        }

        String galleryPath = Environment.getExternalStorageDirectory() + File.separator + Environment.DIRECTORY_DCIM;

        String path = String.format("%s/%s",galleryPath, name);
        File file = new File(galleryPath, name);
        TGLog.d("path = " + path);
        if (file.exists()) {
            return true;
        }
        Bitmap bitmap = ImageUtils.GetImageInputStream(url);
        int ret = ImageUtils.saveFile(TGApplicationBase.getApplication(), bitmap, path);
        if (ret == -1){
            return false;
        }
        return true;
    }

    public static String getDownloadPath(String url){
        String name = AbMd5.MD5(url) + url.substring(url.lastIndexOf("."));
        String galleryPath = Environment.getExternalStorageDirectory()
                + File.separator + Environment.DIRECTORY_DCIM;

        String path = String.format("%s/%s",galleryPath, name);
        File file = new File(galleryPath, name);
        TGLog.d("path = " + path);
        if (file.exists()) {
            return path;
        }
        Bitmap bitmap = GetImageInputStream(url);
        int ret = saveFile(TGApplicationBase.getApplication(), bitmap, path);
        if (ret == -1){
            return "";
        }
        return path;
    }

    public static Bitmap GetImageInputStream(String imageurl){
        URL url;
        HttpURLConnection connection=null;
        Bitmap bitmap=null;
        try {
            url = new URL(imageurl);
            connection=(HttpURLConnection)url.openConnection();
            connection.setConnectTimeout(6000); //超时设置
            connection.setDoInput(true);
            connection.setUseCaches(false); //设置不使用缓存
            InputStream inputStream=connection.getInputStream();
            bitmap= BitmapFactory.decodeStream(inputStream);
            inputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bitmap;
    }

    public static Bitmap getPic100x100(String path){
        Bitmap bitmap = BitmapFactory.decodeFile(path);
        return getPic100x100(bitmap);
    }

    public static Bitmap getPic100x100(Bitmap bitmap){
        return getPic(bitmap, 100, 100);
    }

    public static Bitmap getPic(Bitmap bitmap, int width, int height){
        Bitmap thumbBmp = bitmap;
        if (bitmap != null && bitmap.getHeight()>height && bitmap.getWidth()>width) {
            thumbBmp = Bitmap.createScaledBitmap(bitmap, width, height, true);
            // Notice： 不用调用recycle()了，系统会自动回收的，反而是手动Recycle可能导致一些Crash
        }
        return thumbBmp;
    }

    public static Bitmap getPic(Bitmap bitmap){
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        long size = bitmap.getRowBytes() * height;
        if (size <= 1024 * 1024){
            return bitmap;
        }

        do {
            width = width  >> 1;
            height = height >> 1;
            size = size / 4;
        }while (size > 1024 * 1024);
        Bitmap thumbBmp = bitmap;
        if (bitmap != null && bitmap.getHeight() >= height && bitmap.getWidth() >= width) {
            thumbBmp = Bitmap.createScaledBitmap(bitmap, width, height, true);
            // Notice： 不用调用recycle()了，系统会自动回收的，反而是手动Recycle可能导致一些Crash
        }
        return thumbBmp;
    }

    public static byte[] bitmapBytes(final Bitmap bmp, final boolean needRecycle) {
        int i;
        int j;
        if (bmp.getHeight() > bmp.getWidth()) {
            i = bmp.getWidth();
            j = bmp.getWidth();
        } else {
            i = bmp.getHeight();
            j = bmp.getHeight();
        }

        Bitmap localBitmap = Bitmap.createBitmap(i, j, Bitmap.Config.RGB_565);
        Canvas localCanvas = new Canvas(localBitmap);

        while (true) {
            localCanvas.drawBitmap(bmp, new Rect(0, 0, i, j), new Rect(0, 0,i, j), null);
            // Notice： 不用调用recycle()了，系统会自动回收的，反而是手动Recycle可能导致一些Crash
            ByteArrayOutputStream localByteArrayOutputStream = new ByteArrayOutputStream();
            localBitmap.compress(Bitmap.CompressFormat.JPEG, 100,
                    localByteArrayOutputStream);
            // Notice： 不用调用recycle()了，系统会自动回收的，反而是手动Recycle可能导致一些Crash
            byte[] arrayOfByte = localByteArrayOutputStream.toByteArray();
            try {
                localByteArrayOutputStream.close();
                return arrayOfByte;
            } catch (Exception e) {
                //F.out(e);
            }
            i = bmp.getHeight();
            j = bmp.getHeight();
        }
    }


    public static int saveFile(Context context, Bitmap bitmap, String path){

        int ret = 0;
        // 声明文件对象
        File file = null;
        // 声明输出流
        FileOutputStream outStream = null;

        try {
            // 如果有目标文件，直接获得文件对象，否则创建一个以filename为名称的文件
            file = new File(path);
            // 获得文件相对路径
            String fileName = file.toString();
            // 获得输出流，如果文件中有内容，追加内容
            outStream = new FileOutputStream(fileName);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, outStream);
            //通知相册更新
            Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
            Uri uri = Uri.fromFile(file);
            intent.setData(uri);
            context.sendBroadcast(intent);
            // Notice： 不用调用recycle()了，系统会自动回收的，反而是手动Recycle可能导致一些Crash

        } catch (Exception e) {
            ret = -1;
            e.getStackTrace();
        } finally {
            try {
                if (outStream != null) {
                    outStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
                ret = -1;
            }
        }


        return ret;
    }
    public static Drawable toGrayscale(Drawable mDrawable) {
        mDrawable.mutate();
        ColorMatrix cm = new ColorMatrix();
        cm.setSaturation(0);
        ColorMatrixColorFilter cf = new ColorMatrixColorFilter(cm);
        mDrawable.setColorFilter(cf);
        return mDrawable;
    }

    /**
     * 使用Drawable新建Bitmap
     */
    public static Bitmap createBitmapWithDrawable(Drawable drawable) {
        Bitmap.Config config = (drawable.getOpacity() != PixelFormat.OPAQUE) ? (Bitmap.Config.ARGB_8888) : (Bitmap.Config.RGB_565);
        Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), config);
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
        drawable.draw(canvas);
        return bitmap;
    }

    public static void loadImage(Context context, final ImageView imageView, String url, boolean disable, final boolean isCar) {
        loadImage(context, imageView, url, disable, isCar, null);
    }

    public static void loadImage(Context context, final ImageView imageView, String url, int placeHolderRes, final ImageLoadListener imageLoadListener) {
        if (!StringUtils.isEmpty(url)) {

            boolean skipMemoryCache = false;
            DiskCacheStrategy diskCacheStrategy = DiskCacheStrategy.NONE;
            RequestOptions requestOptions = new RequestOptions().skipMemoryCache(skipMemoryCache).diskCacheStrategy(diskCacheStrategy).dontAnimate().placeholder(placeHolderRes);

            if (imageView != null) {
                imageView.setTag(R.id.image_load_tag, url);
            }

            Glide.with(context).load(url).thumbnail(0.5f)
                    .apply(requestOptions)
                    .into(new SimpleTarget<Drawable>() {
                        @Override
                        public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
                            if (imageView != null && imageView.getTag(R.id.image_load_tag) != null && imageView.getTag(R.id.image_load_tag) instanceof String) {
                                String tagUrl = (String) imageView.getTag(R.id.image_load_tag);
                                if (tagUrl != null && tagUrl.equals(url)) {

                                    imageView.setImageDrawable(resource);
                                    if (imageLoadListener != null) {
                                        if (resource instanceof BitmapDrawable) {
                                            Bitmap bitmap = ((BitmapDrawable) resource).getBitmap();
                                            imageLoadListener.onLoaded(bitmap);
                                        }
                                    }

                                } else {
                                    Log.i("asdasdasdfffff", "onResourceReady: skip");
                                }
                            }
                        }

                        @Override
                        public void onLoadFailed(@Nullable Drawable errorDrawable) {
                            imageView.setImageResource(placeHolderRes);
                        }
                    });
        }

    }

    public static void loadImage(Context context, final ImageView imageView, String url, int placeHolderRes, boolean disable, final boolean isCar, final ImageLoadListener imageLoadListener) {
        TGLog.d(TAG, "url = " + url);
        if (!StringUtils.isEmpty(url)) {
            boolean skipMemoryCache = false;
            DiskCacheStrategy diskCacheStrategy = DiskCacheStrategy.RESOURCE;
            if (url.startsWith("/")){
                skipMemoryCache = true;
                diskCacheStrategy = DiskCacheStrategy.NONE;
            }
            RequestOptions requestOptions;
            if (placeHolderRes == 0){
                requestOptions = new RequestOptions().skipMemoryCache(skipMemoryCache).diskCacheStrategy(diskCacheStrategy).dontAnimate();
            }else{
                requestOptions = new RequestOptions().skipMemoryCache(skipMemoryCache).diskCacheStrategy(diskCacheStrategy).dontAnimate().placeholder(placeHolderRes);
            }
            if (disable) {
                GrayscaleTransformation transformation = new GrayscaleTransformation();
                RequestOptions other = RequestOptions.bitmapTransform(transformation);
                requestOptions.apply(other);
            }



            if (imageView != null) {
                imageView.setTag(R.id.image_load_tag, url);
            }

            Glide.with(context).load(url).thumbnail(0.5f)
                    .apply(requestOptions)
                    .into(new SimpleTarget<Drawable>() {
                        @Override
                        public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
                            if (imageView != null && imageView.getTag(R.id.image_load_tag) != null && imageView.getTag(R.id.image_load_tag) instanceof String) {
                                String tagUrl = (String) imageView.getTag(R.id.image_load_tag);
                                if (tagUrl != null && tagUrl.equals(url)) {
                                    imageView.setTag(R.id.image_load_tag, "");
                                    imageView.setImageDrawable(resource);
                                    if (imageLoadListener != null) {
                                        if (resource instanceof BitmapDrawable) {
                                            Bitmap bitmap = ((BitmapDrawable) resource).getBitmap();
                                            imageLoadListener.onLoaded(bitmap);
                                        }
                                    }

                                }
                            }
                        }

                        @Override
                        public void onLoadFailed(@Nullable Drawable errorDrawable) {
                            String tagUrl = (String) imageView.getTag(R.id.image_load_tag);
                            if (tagUrl != null && tagUrl.equals(url)) {
                                imageView.setTag(R.id.image_load_tag, "");
                              //  setDefaultImage(isCar, imageView);
                            }

                        }
                    });
        }

    }

    public static void loadImage(Context context, final ImageView imageView, String url, boolean disable, final boolean isCar, final ImageLoadListener imageLoadListener) {
        loadImage(context, imageView, url, R.drawable.image_default_rounded_bg, disable, isCar, imageLoadListener);
    }

    public static void setDefaultImage(boolean isCar, ImageView imageView) {
        if (isCar) {
            imageView.setImageResource(R.mipmap.drive_map_default);
        } else {
            imageView.setImageResource(R.drawable.image_default_rounded_bg);
        }
    }

    public static void loadImage(Context context, final View bgView , final String url,boolean disable){
        if (TextUtils.isEmpty(url)) return;
        boolean skipMemoryCache = false;
        DiskCacheStrategy diskCacheStrategy = DiskCacheStrategy.RESOURCE;
        if (url.startsWith("/")) {
            skipMemoryCache = true;
            diskCacheStrategy = DiskCacheStrategy.NONE;
        }
        RequestOptions requestOptions = new RequestOptions().skipMemoryCache(skipMemoryCache).diskCacheStrategy(diskCacheStrategy).dontAnimate();
        if (disable) {
            GrayscaleTransformation transformation = new GrayscaleTransformation();
            RequestOptions other = RequestOptions.bitmapTransform(transformation);
            requestOptions.apply(other);
        }
        if (!((Activity) context).isFinishing()) {
            Glide.with(context).load(url).thumbnail(0.5f).apply(requestOptions).into(new SimpleTarget<Drawable>() {
                @Override
                public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
                    bgView.setBackground(resource);
                }

                @Override
                public void onLoadFailed(@Nullable Drawable errorDrawable) {
                    super.onLoadFailed(errorDrawable);
                }
            });
        }
    }

    public static void loadImage(Context context, ImageView iv ,String url){
        if (TextUtils.isEmpty(url)) return;

        boolean skipMemoryCache = false;
        DiskCacheStrategy diskCacheStrategy = DiskCacheStrategy.RESOURCE;
        if (url.startsWith("/")) {
            skipMemoryCache = true;
            diskCacheStrategy = DiskCacheStrategy.NONE;
        }

        RequestOptions requestOptions = new RequestOptions().skipMemoryCache(skipMemoryCache).diskCacheStrategy(diskCacheStrategy).dontAnimate();

        if (!((Activity) context).isFinishing()) {
            Glide.with(context).load(url).thumbnail(0.5f).apply(requestOptions).into(new SimpleTarget<Drawable>() {
                @Override
                public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
                    iv.setImageDrawable(resource);
                }

                @Override
                public void onLoadFailed(@Nullable Drawable errorDrawable) {
                    super.onLoadFailed(errorDrawable);
                }
            });
        }
    }

    public static void loadImage(Context context, final ImageView imageView, Bitmap bitmap, boolean disable, final boolean isCar) {
        loadImage(context, imageView, bitmap, disable, isCar, null);
    }

    public static void loadImage(Context context, final ImageView imageView, Bitmap bitmap, boolean disable, final boolean isCar, final ImageLoadListener imageLoadListener) {
        if (bitmap!=null) {
            boolean skipMemoryCache = true;
            DiskCacheStrategy diskCacheStrategy = DiskCacheStrategy.NONE;

            RequestOptions requestOptions = new RequestOptions().skipMemoryCache(skipMemoryCache).diskCacheStrategy(diskCacheStrategy).dontAnimate().placeholder(R.drawable.image_default_rounded_bg);
            if (disable) {
                GrayscaleTransformation transformation = new GrayscaleTransformation();
                RequestOptions other = RequestOptions.bitmapTransform(transformation);
                requestOptions.apply(other);
            }

            Glide.with(context).load(bitmap).thumbnail(0.5f)
                    .apply(requestOptions)
                    .into(new SimpleTarget<Drawable>() {
                        @Override
                        public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
                            if (imageLoadListener != null){
                                if (resource instanceof BitmapDrawable) {
                                    Bitmap bitmap = ((BitmapDrawable) resource).getBitmap();
                                    imageLoadListener.onLoaded(bitmap);
                                }
                            }else{
                                imageView.setImageDrawable(resource);
                            }

                        }

                        @Override
                        public void onLoadFailed(@Nullable Drawable errorDrawable) {
                            if (imageLoadListener != null){
                                imageLoadListener.onLoaded(null);
                            }else{
                                setDefaultImage(isCar, imageView);
                            }


                        }
                    });
        }
    }

    /**
     * 按正方形裁切图片
     */
    public static Bitmap ImageCrop(Bitmap bitmap, boolean isRecycled) {

        if (bitmap == null) {
            return null;
        }

        int w = bitmap.getWidth(); // 得到图片的宽，高
        int h = bitmap.getHeight();

        int wh = Math.min(w, h);// 裁切后所取的正方形区域边长

        int retX = w > h ? (w - h) / 2 : 0;// 基于原图，取正方形左上角x坐标
        int retY = w > h ? 0 : (h - w) / 2;

        return createImage(bitmap, isRecycled, retX, retY, wh, wh);
    }

    public static Bitmap ImageCrop(Bitmap bitmap, int width, int height, boolean isRecycled) {

        if (bitmap == null) {
            return null;
        }

        int w = bitmap.getWidth(); // 得到图片的宽，高
        int h = bitmap.getHeight();
        int retX = 0;
        int retY = 0;
        int ww = w;
        int hh = h;
        float f = (float)w / h;
        float f1 = (float)width / height;

        if (f > f1){
            ww = h * width / height;
            retX = (w - ww) / 2;
        }else{
            hh = ww * height / width;
            retY = (h - hh) / 2;
        }

        return createImage(bitmap, isRecycled, retX, retY, ww, hh);
    }

    public static Bitmap ImageCropFromRotation(Bitmap bitmap, boolean isRecycled, int scaleW, int scaleH) {

        if (bitmap == null) {
            return null;
        }


        int w = bitmap.getWidth(); // 得到图片的宽，高
        int h = bitmap.getHeight();
        int retX = 0;
        int retY = 0;
        int ww = w;
        int hh = w * scaleH / scaleW;
        if (hh <= h){
            retY = (h - hh) / 2;
        }else{
            hh = h;
            ww = w * scaleW / scaleH;
            if (ww <= w){
                retX = (w - ww) / 2;
            }
        }

        return createImage(bitmap, isRecycled, retX, retY, ww, hh);
    }

    public static Bitmap adjustPhotoRotation(Bitmap bm, final int orientationDegree) {

        Matrix m = new Matrix();
        m.setRotate(orientationDegree, (float) bm.getWidth() / 2, (float) bm.getHeight() / 2);

        try {
            Bitmap bm1 = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), m, true);

            return bm1;

        } catch (OutOfMemoryError ex) {
        }
        return null;

    }

    private static Bitmap createImage(Bitmap bitmap, boolean isRecycled, int retX, int retY, int ww, int hh) {
        Bitmap bmp = Bitmap.createBitmap(bitmap, retX, retY, ww, hh, null,
                false);
        if (isRecycled && bitmap != null && !bitmap.equals(bmp)
                && !bitmap.isRecycled()) {
            // Notice： 不用调用recycle()了，系统会自动回收的，反而是手动Recycle可能导致一些Crash
        }
        return bmp;
    }


    public static void saveImage(Context context, String url) {
        TGThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    Bitmap myBitmap = Glide.with(context).asBitmap()
                            .skipMemoryCache(true)//跳过内存缓存
                            .diskCacheStrategy(DiskCacheStrategy.NONE)//不缓冲disk硬盘中
                            .load(url)
                            .submit(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL).get();
                    Bitmap bitmap = Bitmap.createBitmap(myBitmap, 0, 0, myBitmap.getWidth(), myBitmap.getHeight());
                    Log.e("wwww", bitmap.toString());
                    saveFile(context, bitmap);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });

    }


    public static List<Integer> getPicList(int count) {
        ArrayList pictureList = new ArrayList();
        for (int i = 0; i < count; i++) {
            int drawable = ResourcesUtil.getResources().getIdentifier("bg_card0", "drawable", TGApplicationBase.getApplicationContext().getPackageName());
            pictureList.add(drawable);
        }
        return pictureList;
    }

    public interface ImageLoadListener {
        void onLoaded(Bitmap bitmap);
    }
}